import csv, json, time

INFLUENCE_INFO = {"-1": "漏洞网页不存在",
                  "4": "不影响",
                  "2": "影响",
                  "3": "不计划修复",
                  "99": "没有该版本系统信息",
                  "-99": "网络请求失败超过5次"}


class KylinCveRecord:
    @classmethod
    # 漏洞处理完成后，对所有cve数据进行总结
    def processor_summary(self, cvereports) -> None:
        # CVE网页未收录
        def _cvelist_cvenotfound_output(cvereports):
            count = 0
            namelist = []
            for cvereport in cvereports:
                if cvereport.influence == -1:
                    count = count + 1
                    namelist.append(cvereport.cve_number)
            print("CVE漏洞未收录： {}个，  列表如下 {}".format(count, "  ".join(namelist)))
        # CVE没有对应版本解决方案
        def _cvelist_solutionnotfound_output(cvereports):
            count = 0
            namelist = []
            for cvereport in cvereports:
                if cvereport.influence == 99:
                    count = count + 1
                    namelist.append(cvereport.cve_number)
            print("CVE漏洞收录，但未有对应版本解决方案： {}个，  列表如下: {}".format(count, "  ".join(namelist)))
        # CVE需要升级包
        def _cvelist_needupdate_package_output(cvereports):
            packlist = []
            for cvereport in cvereports:
                if cvereport.influence == 2:
                    for fix_pack in cvereport.solution:
                        if fix_pack["packname"] not in packlist:
                            packlist.append(fix_pack["packname"])
            print("需要升级的包如下: ", " ".join(packlist))

        # -----------------------------------------
        print("--------------------> 漏洞处理结果如下 <--------------------")
        print("处理CVE漏洞总计： {}个".format(len(cvereports)))
        # ---- 搜索状态异常cve信息输出
        _cvelist_cvenotfound_output(cvereports)
        _cvelist_solutionnotfound_output(cvereports)
        _cvelist_needupdate_package_output(cvereports)

    # 用于向csv文件记录多个漏洞结果
    @classmethod
    def record_cvereports2csv(cls, all_cve_reports, outputfilepath, productidlist) -> None:
        with open(outputfilepath, 'w', encoding='UTF-8') as f:
            writer = csv.writer(f, dialect='unix')
            for cvereport in all_cve_reports:
                # 输出格式  漏洞编号、漏洞详情、漏洞影响情况、漏洞解决方案、产品编号、架构
                line = [cvereport.cve_number,
                        cvereport.detail,
                        INFLUENCE_INFO.get(str(cvereport.influence), "返回值异常"),
                        ["{}: {}: {}".format(fix_pack["packname"],fix_pack["status"], fix_pack["version"]) for fix_pack in cvereport["solution"]],
                        productidlist[cvereport.productid],
                        cvereport.framework]
                writer.writerow(line)

    # # 用于向日志文件记录多个漏洞信息
    # @classmethod
    # def _record_cvereports2log(cls, all_cve_reports) -> None:
    #     for cve_report in all_cve_reports:
    #         log_format_info =(  "--------> 处理漏洞：{} <--------\n"
    #                             "  时间： {}\n"
    #                             "  CVE编号： {}\n"
    #                             "  产品id: {} ---- {}\n"
    #                             "  CPU架构： {}\n"
    #                             "  内网CVE链接： {}\n"
    #                             "  状态: {}({})\n"
    #                             "  解决方案: {}".format(
    #                                                     cve_report["cve_number"],
    #                                                     time.strftime("%Y-%m-%d %H:%M:%S"),
    #                                                     cve_report["cve_number"],
    #                                                     cve_report["productid"], product_id[cve_report["productid"]],
    #                                                     cve_report["framework"],
    #                                                     "https://server.kylinos.cn:18089/cve/detail?allTitle=" + cve_report["cve_number"],
    #                                                     cve_report["influence"], INFLUENCE_INFO.get(str(cve_report["influence"]), "返回值异常"),
    #                                                     ["{}: {}: {}".format(i["packname"],i["status"], i["version"]) for i in cve_report["solution"]])
    #                         )
    #         # -------- 写入日志 --------
    #         logger = logging.getLogger("自动化漏洞搜索工具")
    #         logging.basicConfig(filename=LogFile, level=logging.INFO, encoding="UTF-8")
    #         logger.info(log_format_info)

    @classmethod
    # 用于写入json文件
    def record_cvereports2json(cls, all_cve_reports, outputfilepath, productidlist):
        all_cve_json_data = []
        for cve_report in all_cve_reports:
            data = {
                "cve_number": cve_report["cve_number"],
                "productid": str(cve_report["productid"]),
                "productname": productidlist[cve_report["productid"]],
                "framework": cve_report["framework"],
                "solution": cve_report["solution"]
            }
            all_cve_json_data.append(data)

        # 写入json文件
        with open(outputfilepath, 'w', encoding="UTF-8") as f:
            json.dump(all_cve_json_data, f,
                      indent=4,
                      ensure_ascii=False,
                      sort_keys=True)